/* 材质替换器：同时为“场景加载”和“手动交互”这两种方式提供材质替换功能 */
// 第三方库
import * as THREE from "three";
// 项目公用
import { type MaterialLoader, materialLoader } from "./MaterialLoader";
import { findObjectMeshByIndex } from "./utils/object-op";

export class MaterialReplacer {
  /**
   * 所使用的材质加载器
   */
  materialLoader: MaterialLoader;

  /**
   * 材质替换器
   * @param userMaterialLoader 所使用的材质加载器
   */
  constructor(userMaterialLoader?: MaterialLoader) {
    if (userMaterialLoader) this.materialLoader = userMaterialLoader;
    else this.materialLoader = materialLoader;
  }

  /**
   * 为模型物体替换材质
   * @param object 要替换材质的目标模型物体
   * @param meshIndex 具体是内部的哪一个 Mesh 要替换材质
   * @param materialId 要替换为的材质的 ID
   */
  replaceModelObject(
    object: THREE.Object3D,
    meshIndex: number,
    materialId: string
  ) {
    // console.log('正在替换材质', object, meshIndex, materialId)
    const mesh = findObjectMeshByIndex(object, meshIndex);
    if (mesh == null) {
      console.warn(
        `[MaterialReplacer] 在此物体中找不到索引为“${meshIndex}”的网格体:`,
        object
      );
    } else {
      this.replaceMesh(mesh, materialId);
    }
  }

  /**
   * 为网格体替换材质
   * @param mesh 要替换材质的网格体
   * @param materialId 要替换为的材质的 ID
   */
  replaceMesh(mesh: THREE.Mesh, materialId: string) {
    const material = this.materialLoader.load(materialId);
    mesh.material = material;
  }
}

/**
 * 材质替换器的默认实例
 */
export const materialReplacer = new MaterialReplacer(materialLoader);
